package com.xishu.service;

import com.xishu.bo.SendCount;
import com.xishu.bo.TicketAndLimit;
import com.xishu.client.CustomerEmailClient;
import com.xishu.config.Config;
import com.xishu.entity.Company;
import com.xishu.entity.customer.*;
import com.xishu.entity.shop.DiscountTicket;
import com.xishu.util.DateUtil;
import com.xishu.util.Tools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.xishu.config.Constant.*;

/**
 * 专门处理会员系统的任务服务
 */
public class CustomerTaskService implements Tools {
    private static CustomerTaskService instance = new CustomerTaskService();
    private CompanyService companyService = CompanyService.getInstance();
    private CustomerService customerService = CustomerService.getInstance();
    private CommonService commonService = CommonService.getInstance();
    private CustomerEmailClient customerEmailClient = CustomerEmailClient.getInstance();
    private static Logger logger = LoggerFactory.getLogger(CustomerTaskService.class);


    private CustomerTaskService() {
    }

    public static CustomerTaskService getInstance() {
        return instance;
    }

    /**
     * 查询所有的会员优惠券的配置
     *
     * @return
     */
    public List<VipLevelTicketConfig> findAllVipLevelTicketConfig() {
        VipLevelTicketConfig vipLevelTicketConfig = new VipLevelTicketConfig();
        vipLevelTicketConfig.setEntity(true);

        return commonService.searchAll(vipLevelTicketConfig);
    }

    /**
     * 查询周期性的会员优惠券配置
     *
     * @return
     */
    public List<VipLevelTicketConfig> findPeriodLevelTicketConfig() {
        List<VipLevelTicketConfig> vipLevelTicketConfigList = findAllVipLevelTicketConfig();
        return vipLevelTicketConfigList.stream().filter(p -> {
            PeriodTimeConfig periodTimeConfig = p.getPeriodTimeConfig();
            return getBoolean(!periodTimeConfig.getOnce());
        }).collect(Collectors.toList());
    }

    /**
     * 配置是否在当前时间执行
     *
     * @param periodTimeConfig
     * @return
     */
    public boolean canAction(PeriodTimeConfig periodTimeConfig, Long time) {
        try {
            if (getBoolean(periodTimeConfig.getOnce())) {
                logger.info("once time , not return");
                return false;
            }

            int periodType = getInt(periodTimeConfig.getPeriodType());
            if (periodType == PERIOD_TYPE_YEAR) {
                int month = getInt(periodTimeConfig.getMonth());
                int day = getInt(periodTimeConfig.getDay());

                if (!isPeriodTimeValid(periodTimeConfig)) {
                    logger.info("period time is not valid");
                    return false;
                }

                int currentMonth = DateUtil.getMonth(time);
                int currentDay = DateUtil.getDay(time);

                //月不相同，肯定不行
                if (month != currentMonth) {
                    return false;
                }

                //特殊情况，如果是2月份，设置的28号，29号，均按照28号来处理
                if (month == 2) {
                    if (Arrays.asList(28, 29).contains(day)) {
                        if (currentDay == 28) {
                            return true;
                        } else {
                            return false;
                        }
                    }
                }

                //剩下的天数也要相等
                return currentDay >= day;
            } else if (periodType == PERIOD_TYPE_MONTH) {
                int day = getInt(periodTimeConfig.getDay());

                if (!isPeriodTimeValid(periodTimeConfig)) {
                    logger.info("period time is not valid");
                    return false;
                }

                int currentDay = DateUtil.getDay(time);

                //如果日期比设置的要大，那么同意发送
                if (currentDay >= day) {
                    return true;
                }

                //如果小了，那么要看是否是月底
                if (day == 31 || day == 30) {
                    //月底发送，主要是针对2月份
                    if (DateUtil.isLastDayOfMonth(new Date(time))) {
                        return true;
                    }
                }

                return false;
            } else if (periodType == PERIOD_TYPE_WEEK) {
                int weekDay = getInt(periodTimeConfig.getWeekDay());

                if (!isPeriodTimeValid(periodTimeConfig)) {
                    logger.info("period time is not valid");
                    return false;
                }

                int currentDayOfWeek = DateUtil.getDayOfWeek(time);
                return weekDay == currentDayOfWeek;
            } else if (periodType == PERIOD_TYPE_DAY) {
                return true;
            } else {
                logger.info("period type is {}, return false", periodType);
                return false;
            }
        } catch (Exception e) {
            logger.error("e", e);
            return false;
        }
    }

    /**
     * 时间的配置是否合法
     *
     * @param periodTimeConfig
     * @return
     */
    public boolean isPeriodTimeValid(PeriodTimeConfig periodTimeConfig) {
        int periodType = getInt(periodTimeConfig.getPeriodType());
        if (periodType == PERIOD_TYPE_YEAR) {
            int month = getInt(periodTimeConfig.getMonth());
            int day = getInt(periodTimeConfig.getDay());

            if (month <= 0 || month > 12) {
                logger.info("month value error {}", month);
                return false;
            }

            if (day > 31) {
                logger.info("day great than 31 {}", day);
                return false;
            }

            if (day < 0) {
                logger.info("day less than 0 {}", day);
                return false;
            }

            //1,3,5,7,8,10,12  有31号
            //4,6,9,11 只有30号
            if (Arrays.asList(4, 6, 9, 11).contains(month)) {
                if (day > 30) {
                    return false;
                }

                return true;
            } else if (month == 2) {
                //2月份允许28，29都可以
                return day <= 29;
            }

            //其它的1,3,5,7,8,10,12那么均满0 - 31
            return true;
        } else if (periodType == PERIOD_TYPE_MONTH) {
            int day = getInt(periodTimeConfig.getDay());
            return day >= 1 && day <= 31;
        } else if (periodType == PERIOD_TYPE_WEEK) {
            Integer weekDay = getInt(periodTimeConfig.getWeekDay());
            return weekDay >= 1 && weekDay <= 7;
        } else if (periodType == PERIOD_TYPE_DAY) {
            //每天发送，不做校验
            return true;
        } else {
            logger.info("period type is {}, return false", periodType);
            return false;
        }
    }

    /**
     * 构建任务执行与否的时间格式
     * 任务的执行的时间，根据不同的周期来记录，如果是年MM-dd，如果是月MM，如果是周 day-dd,如果是每天，yyyy-MM-dd，如果是定时任务，那么是yyyy-MM-dd
     *
     * @param periodTimeConfig
     * @return
     */
    public String getTaskExecuteTime(PeriodTimeConfig periodTimeConfig) throws Exception {
        int periodType = getInt(periodTimeConfig.getPeriodType());
        if (periodType == PERIOD_TYPE_YEAR) {
            return DateUtil.format(System.currentTimeMillis(), "MM-dd");
        } else if (periodType == PERIOD_TYPE_MONTH) {
            return DateUtil.format(System.currentTimeMillis(), "MM");
        } else if (periodType == PERIOD_TYPE_WEEK) {
            return String.format("day-%s", DateUtil.getCurrentDayOfWeek());
        } else if (periodType == PERIOD_TYPE_DAY) {
            return DateUtil.format(System.currentTimeMillis(), "yyyy-MM-dd");
        } else {
            return "error";
        }
    }

    /**
     * 配置是否已经执行过了
     *
     * @param vipLevelTicketConfig
     * @return
     */
    public boolean isVipLevelTicketTaskDone(VipLevelTicketConfig vipLevelTicketConfig) throws Exception {
        TaskExecuteHistory taskExecuteHistory = new TaskExecuteHistory();
        taskExecuteHistory.setTaskId(vipLevelTicketConfig.getId());
        taskExecuteHistory.setTaskType(CUSTOMER_TASK_TYPE_LEVEL_TICKET);
        taskExecuteHistory.setExecuteTime(getTaskExecuteTime(vipLevelTicketConfig.getPeriodTimeConfig()));
        Optional<TaskExecuteHistory> taskExecuteHistoryOptional = commonService.searchOneOptional(taskExecuteHistory);
        return taskExecuteHistoryOptional.isPresent();
    }

    /**
     * 判断用户的任务是否已经执行过了
     *
     * @param customerId
     * @return
     */
    public boolean isBirthdayTaskDone(Long customerId) {
        TaskExecuteHistory taskExecuteHistory = new TaskExecuteHistory();
        taskExecuteHistory.setCustomerId(customerId);
        taskExecuteHistory.setTaskType(CUSTOMER_TASK_BIRTHDAY_TEMPLATE_TICKET);

        //会员的生日券处理
        taskExecuteHistory.setSortField(new String[]{"createTime"});
        taskExecuteHistory.setSortType("DESC");
        Page<TaskExecuteHistory> historyPage = commonService.search(taskExecuteHistory);

        //从来没有执行过
        if (historyPage.getTotalElements() == 0) {
            return false;
        }

        //生日券只要最近2个月发送过，将不再重复发送
        List<TaskExecuteHistory> taskExecuteHistoryList = historyPage.getContent();
        Optional<TaskExecuteHistory> taskExecuteHistoryOptional = taskExecuteHistoryList.stream().filter(taskHistory -> {
            return Math.abs(System.currentTimeMillis() - taskHistory.getCreateTime()) <= DateUtil.ONE_MONTH * 2;
        }).findAny();

        return taskExecuteHistoryOptional.isPresent();
    }

    /**
     * 将优惠券送给对应级别的会员账号
     *
     * @param vipLevelTicketConfig
     */
    public void addTicketToVipLevelCustomer(VipLevelTicketConfig vipLevelTicketConfig) throws Exception {
        //送给VIP的
        if (getBoolean(vipLevelTicketConfig.getVip())) {
            addTicketToVipCustomer(vipLevelTicketConfig);
            return;
        }

        addTicketToCommonUser(vipLevelTicketConfig);
    }

    /**
     * 将优惠券送给VIP账号
     *
     * @param vipLevelTicketConfig
     */
    public void addTicketToVipCustomer(VipLevelTicketConfig vipLevelTicketConfig) throws Exception {
        CustomerService.getInstance().allCustomerAction(vipLevelTicketConfig.getCompanyId(), true, (customer -> {
            addTicketToCustomer(vipLevelTicketConfig, customer);
        }));
    }

    /**
     * 将优惠券按照普通会员来发送给会员(VIP会员也属于会员的一种)
     *
     * @param vipLevelTicketConfig
     */
    public void addTicketToCommonUser(VipLevelTicketConfig vipLevelTicketConfig) {
        CustomerService.getInstance().allCustomerAction(vipLevelTicketConfig.getCompanyId(), null, (customer -> {
            //只有等级相同的会员才发送优惠券
            if (equals(customer.getVipLevelId(), vipLevelTicketConfig.getLevelId())) {
                addTicketToCustomer(vipLevelTicketConfig, customer);
            }
        }));
    }

    /**
     * 将优惠券发给某一个用户
     *
     * @param vipLevelTicketConfig
     * @param customer
     */
    private void addTicketToCustomer(VipLevelTicketConfig vipLevelTicketConfig, Customer customer) {
        try {
            Long ticketId = vipLevelTicketConfig.getTicketId();

            DiscountTicketService discountTicketService = DiscountTicketService.getInstance();
            DiscountTicket discountTicket = discountTicketService.findTicket(ticketId);
            int ticketNumber = getInt(vipLevelTicketConfig.getTicketNumber());

            //至少送一张
            if (ticketNumber <= 0) {
                ticketNumber = 1;
            }

            for (int i = 0; i < ticketNumber; i++) {
                addTicketToCustomer(customer, discountTicket, getBoolean(vipLevelTicketConfig.getVip()),
                        getBoolean(vipLevelTicketConfig.getLimitNumber()));
            }
        } catch (Exception e) {
            logger.error("e", e);
        }
    }

    /**
     * 添加优惠券给会员
     *
     * @param customer
     * @param parentTicketId
     */
    public void addTicketToCustomer(Customer customer, Long parentTicketId) throws Exception {
        DiscountTicketService discountTicketService = DiscountTicketService.getInstance();
        DiscountTicket parentTicket = discountTicketService.findTicket(parentTicketId);
        addTicketToCustomer(customer, parentTicket, false, true);
    }

    /**
     * 添加一批优惠券给会员
     *
     * @param customer
     * @param ticketAndLimitList
     * @throws Exception
     */
    public void addTicketToCustomer(Customer customer, List<TicketAndLimit> ticketAndLimitList) {
        if (isEmpty(ticketAndLimitList)) {
            logger.info("the ticket and limit is empty");
            return;
        }

        for (TicketAndLimit ticketAndLimit : ticketAndLimitList) {
            try {
                Integer ticketNumber = getInt(ticketAndLimit.getTicketNumber());
                for (Integer i = 0; i < ticketNumber; i++) {
                    DiscountTicket parentTicket = DiscountTicketService.getInstance().findTicket(ticketAndLimit.getTicketId());
                    addTicketToCustomer(customer, parentTicket, false, getBoolean(ticketAndLimit.getLimitNumber()));
                }
            } catch (Exception e) {
                logger.error("e", e);
            }
        }
    }

    /**
     * 将真实的优惠券添加给会员
     * 如果是线上券，那么创建新的券，如果是
     *
     * @param customer
     * @param parentTicket
     * @param vip
     * @param limitNumber
     * @throws Exception
     */
    public void addTicketToCustomer(Customer customer, DiscountTicket parentTicket, boolean vip, Boolean limitNumber) throws Exception {
        DiscountTicketService discountTicketService = DiscountTicketService.getInstance();
        CustomerTicket customerTicket = new CustomerTicket();
        customerTicket.setCustomerId(customer.getId());
        DiscountTicket realTicket = discountTicketService.createRealTicket(parentTicket);
        customerTicket.setTicketId(realTicket.getId());
        customerTicket.setVip(vip);
        customerTicket.setCompanyId(realTicket.getCompanyId());

        if (parentTicket.getParentId() != null) {
            //这里是实体券
            customerTicket.setParentTicketId(parentTicket.getParentId());
        } else {
            customerTicket.setParentTicketId(parentTicket.getId());
        }

        customerTicket.setUsed(false);
        customerTicket.setExpired(false);
        customerTicket.setCode(realTicket.getCode());
        //计算过期时间
        if (getInt(parentTicket.getValidType()) == TICKET_VALID_TYPE_TIME) {
            logger.info("set the ticket expired time to {}", parentTicket.getEndTime());
            customerTicket.setExpiredTime(parentTicket.getEndTime());
        } else {
            //设置了送券之后多少天
            long currentTimeMillis = System.currentTimeMillis();
            long expireTime = DateUtil.endTimeInDay(currentTimeMillis + getInt(realTicket.getBindingDays()) * DateUtil.ONE_DAY);

            logger.info("set the ticket expired time to binding days {}", realTicket.getBindingDays());

            if (getInt(realTicket.getBindingDays()) <= 0) {
                logger.info("the binding days is 0");
            }

            customerTicket.setExpiredTime(expireTime);
            customerTicket.setExpiredDate(DateUtil.formatDate(expireTime));
            realTicket.setStartTime(currentTimeMillis);
            realTicket.setEndTime(expireTime);
            commonService.save(realTicket);
        }

        if (System.currentTimeMillis() > customerTicket.getExpiredTime()) {
            customerTicket.setExpired(true);
        }

        customerTicket.setLimitNumber(limitNumber);
        customerTicket.setTicketName_zh(discountTicketService.getTicketNameZh(parentTicket));
        customerTicket.setTicketName_en(discountTicketService.getTicketNameEn(parentTicket));
        commonService.createObject(customerTicket);
    }

    //计算生日营销里面的计划配额,只有邮件
    public void calBirthDayEmailCount(Company company, long endTime, SendCount sendCount) throws Exception {
        Long companyId = company.getId();

        MarketBirthdayTemplate birthdayTemplate = customerService.findBirthdayTemplate(companyId);
        if (getInt(birthdayTemplate.getRemindTime()) == 0) {
            logger.info("do not config the remind time");
            return;
        }

        if (!getBoolean(birthdayTemplate.getEnable())) {
            logger.info("enable is disable");
            return;
        }

        //先找出要过生日的用户
        Customer reqCustomer = new Customer();
        reqCustomer.setCompanyId(companyId);
        //必须要是有生日的
        reqCustomer.setStartBirthDay(0l);

        commonService.doAll(reqCustomer, (customerInDb) -> {
            calBirthDayTaskForCustomer(endTime, sendCount, customerInDb);
        });
    }

    /**
     * 计算VIP续费邮件需要多少量
     *
     * @param company
     * @param endTime
     * @param sendCount
     */
    public void calVipRenewTaskEmailCount(Company company, long endTime, SendCount sendCount) {
        try {
            VipRenewEmailTemplate vipRenewEmailTemplateQuery = new VipRenewEmailTemplate();
            vipRenewEmailTemplateQuery.setCompanyId(company.getId());
            Optional<VipRenewEmailTemplate> vipRenewEmailTemplateOptional = commonService.searchOneOptional(vipRenewEmailTemplateQuery);

            //还没有配置提供模板
            if (!vipRenewEmailTemplateOptional.isPresent()) {
                logger.info("can not find the renew email template");
                return;
            }

            VipRenewEmailTemplate vipRenewEmailTemplate = vipRenewEmailTemplateOptional.get();
            //提供时间问题
            if (vipRenewEmailTemplate.getRemindDay() == null || vipRenewEmailTemplate.getRemindDay() < 1) {
                logger.info("remind day is {}", vipRenewEmailTemplate.getRemindDay());
                return;
            }

            //内容或者标题有问题也不发
            if (isEmpty(vipRenewEmailTemplate.getTitle()) || isEmpty(vipRenewEmailTemplate.getContent())) {
                logger.info("vip title or content empty");
                return;
            }

            //找出是VIP用户,计算的结束时间 - N *  天数 大于 VIP的结束时间
            Customer reqCustomer = new Customer();
            reqCustomer.setCompanyId(company.getId());
            reqCustomer.setEndVipEndTime(endTime);
            reqCustomer.setVip(true);

            commonService.doAll(reqCustomer, (customerInDb) -> {
                //已经发送过了邮件不再计算
                calVipRenewTaskForCustomer(sendCount, customerInDb, vipRenewEmailTemplate);
            });
        } catch (Exception e) {
            //数据异常了，则不用计算
            logger.error("e", e);
        }
    }

    /**
     * 计算VIP续费的邮件
     *
     * @param sendCount
     * @param customerInDb
     */
    private void calVipRenewTaskForCustomer(SendCount sendCount, Customer customerInDb, VipRenewEmailTemplate vipRenewEmailTemplate) {
        if (isEmpty(customerInDb.getEmail())) {
            logger.info("email is empty, calVipRenewTaskForCustomer");
            return;
        }

        long currentTimeMillis = System.currentTimeMillis();

        //在通知范围内，查看最近有没有发送过，如果已经发送过了，那么也不发送
        List<TaskExecuteHistory> customerRenewHistoryList = CustomerTaskService.getInstance().findCustomerRenewHistory(customerInDb.getId());
        //发送历史记录为空，或者在指定时间范围内没有发送过
        if (isEmpty(customerRenewHistoryList) || !customerRenewHistoryList.stream().filter(p -> currentTimeMillis - p.getCreateTime() < vipRenewEmailTemplate.getRemindDay() * DateUtil.ONE_DAY).findAny().isPresent()) {
            sendCount.setEmail(getLong(sendCount.getEmail()) + 1);
        }
    }

    /**
     * 计算生日邮件数量
     *
     * @param endTime
     * @param sendCount
     * @param customerInDb
     */
    private void calBirthDayTaskForCustomer(long endTime, SendCount sendCount, Customer customerInDb) {
        try {
            if (isEmpty(customerInDb.getEmail())) {
                logger.info("email is empty");
                return;
            }

            //需要判断该任务执行过了吗，一个月以内发送过了，那么不再重复发送，因为时间发送有可能会更新
            boolean taskDone = isBirthdayTaskDone(customerInDb.getId());
            if (taskDone) {
                logger.info("the user send the birthday template");
                return;
            }

            //如果没有生日，不做计算
            if (getLong(customerInDb.getBirthDay()) == 0) {
                logger.info("do not has the birth day");
                return;
            }

            //获取生日的日期，要在当前日期和结束日期之间的
            long birthDay = DateUtil.endTimeInDay(getBirthDayForYear(getLong(customerInDb.getBirthDay())));
            if (birthDay > System.currentTimeMillis() && birthDay <= endTime) {
                logger.info("add the customer to birthday email count {}", customerInDb.getId());
                sendCount.setEmail(getLong(sendCount.getEmail()) + 1);
            } else {
                logger.info("the customer do not in the time {}", customerInDb.getId());
            }
        } catch (Exception e) {
            //数据异常了，则不用计算
            logger.error("e", e);
        }
    }

    /**
     * 获取某一年的生日
     *
     * @param customerBirthDay
     * @return
     */
    public long getBirthDayForYear(long customerBirthDay) {
        int month = Integer.parseInt(DateUtil.format(customerBirthDay, "MM"));
        int day = Integer.parseInt(DateUtil.format(customerBirthDay, "dd"));

        if (month == 2 && day == 29) {
            day = 28;
        }

        long currentTimeMillis = System.currentTimeMillis();

        //获取生日当天时间
        int currentYear = Integer.parseInt(DateUtil.format(currentTimeMillis, "yyyy"));

        //今年的生日时间
        long birthdayTime = DateUtil.dateToTime(currentYear, month, day);


        if (currentTimeMillis > birthdayTime) {
            long nextYearBirthday = DateUtil.dateToTime(currentYear + 1, month, day);
            birthdayTime = nextYearBirthday;
        }

        return birthdayTime;
    }

    /**
     * 处理一个公司的生日邮件任务
     *
     * @param company
     */
    public void dealCompanyBirthDayTicket(Company company) throws Exception {
        if (company == null) {
            logger.info("company is null");
            return;
        }

        if (company.getId() == null) {
            logger.info("company id is null");
            return;
        }

        Long companyId = company.getId();
        logger.info("company {} dealCompanyBirthDayTicket", companyId);

        //生日邮件的营销历史记录
        MarketHistory marketHistory = new MarketHistory();
        marketHistory.setCompanyId(companyId);
        marketHistory.setTaskName_zh(Config.getInstance().birthday_task_name_zh());
        marketHistory.setTaskName_en(Config.getInstance().birthday_task_name_en());

        String senderName = customerService.getSenderName(company);

        Customer customer = new Customer();
        customer.setCompanyId(companyId);

        MarketBirthdayTemplate birthdayTemplate = customerService.findBirthdayTemplate(companyId);
        Optional<Quota> quotaOptional = customerService.findQuotaOrCreate(companyId);

        if (!quotaOptional.isPresent()) {
            logger.info("can not find the company {} quota ", companyId);
            return;
        }

        if (getInt(birthdayTemplate.getRemindTime()) == 0) {
            logger.info("do not config the remind time");
            return;
        }

        if (!getBoolean(birthdayTemplate.getEnable())) {
            logger.info("enable is disable");
            return;
        }


        //时间上是否匹配
        Integer hour = getInt(birthdayTemplate.getHour());
        int currentHour = DateUtil.getHour(System.currentTimeMillis());

        if (hour != currentHour) {
            logger.info("not match the hour");
            return;
        }

        Quota quota = quotaOptional.get();
        commonService.setDefaultValue(quota);

        commonService.doAll(customer, (customerInDb) -> {
            try {
                logger.info("check the user {} birthday ", customerInDb.getId());

                //没有生日的会员不处理
                if (getLong(customerInDb.getBirthDay()) == 0) {
                    logger.info("user do not has the birthday");
                    return;
                }

                //需要判断该任务执行过了吗，一个月以内发送过了，那么不再重复发送，因为时间发送有可能会更新
                boolean taskDone = isBirthdayTaskDone(customerInDb.getId());
                if (taskDone) {
                    logger.info("the user send the birthday template");
                    return;
                }

                //提前多少天之内发送
                long currentTimeMillis = System.currentTimeMillis();
                //2月29日均当成2月28日来处理
                Long birthDay = customerInDb.getBirthDay();

                int month = Integer.parseInt(DateUtil.format(birthDay, "MM"));
                int day = Integer.parseInt(DateUtil.format(birthDay, "dd"));

                if (month == 2 && day == 29) {
                    day = 28;
                }

                //获取生日当天时间
                int currentYear = Integer.parseInt(DateUtil.format(currentTimeMillis, "yyyy"));

                //今年的生日时间
                long thisYearBirthday = DateUtil.dateToTime(currentYear, month, day);

                //今年的生日已经过了，那么需要判断明年的生日
                if (currentTimeMillis > thisYearBirthday) {
                    long nextYearBirthday = DateUtil.dateToTime(currentYear + 1, month, day);

                    //按照当天的23：59：59来计算
                    long endTimeInDay = DateUtil.endTimeInDay(currentTimeMillis);
                    nextYearBirthday = DateUtil.endTimeInDay(nextYearBirthday);

                    //应该是1月份过生日，在12月份发送
                    if (nextYearBirthday - endTimeInDay <= birthdayTemplate.getRemindTime() * DateUtil.ONE_DAY) {
                        addTicketToCustomer(customerInDb, getList(birthdayTemplate.getTicketAndLimitList()));
                    } else {
                        //时间不对
                        logger.info("time not match");
                        return;
                    }
                } else {
                    //今年的生日还没有过
                    //在距离的时间范围内
                    long endTimeInDay = DateUtil.endTimeInDay(currentTimeMillis);
                    thisYearBirthday = DateUtil.endTimeInDay(thisYearBirthday);

                    if ((thisYearBirthday - endTimeInDay) <= birthdayTemplate.getRemindTime() * DateUtil.ONE_DAY) {
                        //添加优惠券到用户的优惠券里面
                        addTicketToCustomer(customerInDb, birthdayTemplate.getTicketAndLimitList());
                    } else {
                        //时间不对
                        logger.info("time not match");
                        return;
                    }
                }

                //写发送日志
                writeBirthDayHistory(customerInDb.getId());

                //发送邮件
                //先判断配额，配额已经用完了，不再发送邮件
                if (quota.getEmailCanUsed() <= 0) {
                    logger.info("company {} used out", companyId);
                    return;
                }

                //没有邮件的会员，不处理配额
                if (isEmpty(customerInDb.getEmail())) {
                    logger.info("customer do not have email");
                    return;
                }

                if (isEmpty(birthdayTemplate.getTitle()) || isEmpty(birthdayTemplate.getContent())) {
                    logger.info("title or content is empty");
                    return;
                }

                quota.setEmailUsed(quota.getEmailUsed() + 1);
                quota.setEmailCanUsed(quota.getEmailCanUsed() - 1);
                commonService.save(quota);

                //开始发送邮件
                customerEmailClient.sendEmail(senderName, customerInDb.getEmail(), birthdayTemplate.getTitle(), birthdayTemplate.getContent(), customerInDb);
                customerService.addEmailSendHistory(companyId, true);

                //添加条数
                marketHistory.setPersonCount(getInt(marketHistory.getPersonCount()) + 1);
                marketHistory.setEmailCount(getInt(marketHistory.getEmailCount()) + 1);
            } catch (Exception e) {
                logger.error("e", e);
            }
        });

        if (getInt(marketHistory.getPersonCount()) > 0) {
            commonService.directSave(marketHistory);
        }

    }


    /**
     * 查询会员的通知续费历史记录
     *
     * @param customerId
     * @return
     */
    public List<TaskExecuteHistory> findCustomerRenewHistory(Long customerId) {
        TaskExecuteHistory taskExecuteHistory = new TaskExecuteHistory();
        taskExecuteHistory.setCustomerId(customerId);
        taskExecuteHistory.setTaskType(CUSTOMER_TASK_TYPE_RE_NEW_VIP);
        taskExecuteHistory.setSortField(new String[]{"createTime"});
        taskExecuteHistory.setSortType("DESC");

        return commonService.searchList(taskExecuteHistory);
    }

    /**
     * 写生日任务的日志
     *
     * @param customerId
     */
    public void writeBirthDayHistory(Long customerId) throws Exception {
        TaskExecuteHistory taskExecuteHistory = new TaskExecuteHistory();
        taskExecuteHistory.setCustomerId(customerId);
        taskExecuteHistory.setTaskType(CUSTOMER_TASK_BIRTHDAY_TEMPLATE_TICKET);
        commonService.createObject(taskExecuteHistory);
    }


}
